package com.orangelife.service.feeDetail.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.github.pagehelper.PageHelper;
import com.orangelife.common.MybaitsGenericDaoSubLogic;
import com.orangelife.exception.AppBizException;
import com.orangelife.service.feeDetail.IFeeDetailService;
import com.orangelife.service.feeDetail.modal.PropFeeDetailDto;
import com.orangelife.setting.constant.CodeConst;
import com.orangelife.setting.constant.InfoConst;
import com.orangelife.setting.constant.TypeConst;
import com.orangelife.utils.PropertyUtils;
import com.orangelife.utils.StringUtils;
import com.orangelife.webservice.service.feedetail.entity.ChangeFeeTypeDto;

@Service("feeDetailService")
public class FeeDetailServiceImpl extends MybaitsGenericDaoSubLogic implements
		IFeeDetailService {

	@Override
	public Map<String, Object> getTotalFeeDetailByApartmentID(String apartmentID)
			throws AppBizException {

		Map<String, Object> res = this.getSqlSession().selectOne(
				"PropFeeDetailMapper.getTotalFeeDetail", apartmentID);

		// TODO Auto-generated method stub
		return res;
	}

	@Override
	public int updateType(String apartmentID, String feeTypeID, String feeDate,
			String type, String planID) throws AppBizException {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("apartmentID", apartmentID);
		param.put("feeTypeID", feeTypeID);
		param.put("feeDate", feeDate);
		param.put("type", type);
		param.put("planID", planID);
		int n = this.getSqlSession().update("PropFeeDetailMapper.updateType",
				param);

		return n;
	}

	@Override
	public int updateTypeByPlanID(String apartmentID, String feeTypeID,
			String feeDate, String type, String planID) throws AppBizException {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("apartmentID", apartmentID);
		param.put("feeTypeID", feeTypeID);
		param.put("feeDate", feeDate);
		param.put("type", type);
		param.put("planID", planID);
		int n = this.getSqlSession().update(
				"PropFeeDetailMapper.updateTypeByPlanID", param);

		return n;
	}

	@Override
	public int bauthInsertFeeDetail(List<Map<String, Object>> list)
			throws AppBizException {

		int n = this.getSqlSession().insert(
				"PropFeeDetailMapper.BauthInsertBySelective", list);
		// TODO Auto-generated method stub
		return n;
	}

	@Override
	public List<Map<String, Object>> selectPropFeeDetailByRelevantID(
			String feeDetailID, String apartmentID, String feeTypeID,
			String timetype, String status, String ruleID, String planID,
			String type) throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("feeDetailID", feeDetailID);
		map.put("apartmentID", apartmentID);
		map.put("feeTypeID", feeTypeID);
		map.put("timetype", timetype);
		map.put("status", status);
		map.put("planID", planID);
		map.put("ruleID", ruleID);
		map.put("type", type);

		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailMapper.selectPropFeeDetailDtoByRelevantID", map);
		return list;
	}

	@Override
	public Map<String, Object> _check(String apartmentID,
			List<String> feeDetailIDs) throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();

		param.put("feeDetailIDs", feeDetailIDs);
		param.put("apartmentID", apartmentID);
		Map<String, Object> res = new HashMap<String, Object>();
		List<Map<String, Object>> l = this.getSqlSession().selectList(
				"PropFeeDetailMapper.checkFeeDetailIsPay", param);
		BigDecimal totalCost = BigDecimal.ZERO;

		if (l == null || l.size() != feeDetailIDs.size()) {

			res.put("ispay", 1);

		} else {

			for (Map<String, Object> map : l) {

				totalCost = totalCost.add(new BigDecimal(StringUtils
						.toString(map.get("amount"))));

			}
			res.put("ispay", 0);
			res.put("totalCost", totalCost.toString());
			res.put("feeDetailIDs", l);

		}

		return res;
	}

	@Override
	public List<PropFeeDetailDto> findPropFeeDetailByRelevantID(
			String feeDetailID, String apartmentID, String feeTypeID,
			String timetype, String status, String planID, String type,
			String ruleID, String feeDate) throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("feeDetailID", feeDetailID);
		map.put("apartmentID", apartmentID);
		map.put("feeTypeID", feeTypeID);
		map.put("timetype", timetype);
		map.put("status", status);
		map.put("planID", planID);
		map.put("type", type);
		map.put("ruleID", ruleID);
		map.put("feeDate", feeDate);

		List<PropFeeDetailDto> list = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.findPropFeeDetailDtoByRelevantID",
				map);
		return list;
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int addPropFeeDetail(List<PropFeeDetailDto> propFeeDetails)
			throws AppBizException {

		if (propFeeDetails == null || propFeeDetails.size() <= 0) {
			return 0;
		}
		return this.getSqlSession().insert(
				"PropFeeDetailBauthMapper.bauthInsert", propFeeDetails);
	}

	@Override
	public List<Map<String, Object>> findPropFeeDetailByPage(String commID,
			String feeDate, String feeTypeID, String status, String tsCreate,
			String search, int pageNo, int pageSize) throws AppBizException {
		{

			/************************************************
			 * 设置输入参数
			 ************************************************/
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("commID", commID);
			map.put("feeDate", feeDate);
			map.put("tsCreate", tsCreate);
			map.put("feeTypeID", feeTypeID);
			map.put("search", search);
			map.put("status", status);
			PageHelper.startPage(pageNo, pageSize);
			List<Map<String, Object>> list = this.getSqlSession().selectList(
					"PropFeeDetailSearchMapper.findAllPropFeeDetail", map);
			return list;
		}
	}

	@Override
	public List<Map<String, Object>> checkRuleIDIsUsed(String feeDetailID,
			String apartmentID, String feeTypeID, String timetype,
			String status, String ruleID, String planID, String type)
			throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("feeDetailID", feeDetailID);
		map.put("apartmentID", apartmentID);
		map.put("feeTypeID", feeTypeID);
		map.put("timetype", timetype);
		map.put("status", status);
		map.put("planID", planID);
		map.put("ruleID", ruleID);
		map.put("type", type);

		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailMapper.selectPropFeeDetailDtoByRelevantID1", map);
		return list;

	}

	@Override
	public int setFeeDetailsPay(String apartmentID, List<String> feeDetailIDs,
			Date paytime) throws AppBizException {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("apartmentID", apartmentID);
		param.put("feeDetailIDs", feeDetailIDs);

		if (paytime == null) {
			paytime = new Date();
		}
		param.put("paytime", paytime);
		// TODO Auto-generated method stub
		return this.getSqlSession().update(
				"PropFeeDetailBauthMapper.updateFeeDetailsPay", param);
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int editPropFeeDetail(List<PropFeeDetailDto> propFeeDetails)
			throws AppBizException {

		for (PropFeeDetailDto propFeeDetailDto : propFeeDetails) {
			this.getSqlSession().update(
					"PropFeeDetailMapper.updateByPrimaryKeySelective",
					propFeeDetailDto);
		}
		return 0;

	}

	public int editPropFeeDetail(PropFeeDetailDto propFeeDetail)
			throws AppBizException {

		Assert.notNull(propFeeDetail);
		/************************************************
		 * 判断输入参数的长度以及是否能为空
		 ************************************************/
		if (StringUtils.isBlank(propFeeDetail.getFeeDetailID())) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "ID不可为空");
		}
		PropFeeDetailDto oldPropFeeDetail = this
				.findPropFeeDetailByID(propFeeDetail.getFeeDetailID());

		if (!StringUtils.isBlank(propFeeDetail.getFeeAmount())) {
			if (propFeeDetail.getFeeAmount().length() > 64) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "计费用量长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getFeePrice())) {
			if (propFeeDetail.getFeePrice().length() > 32) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "计费单价长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getTimetype())) {
			if (propFeeDetail.getTimetype().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002,
						"账单时间类型（0,按收费期间1,按开始和结束时间）长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getFeeDate())) {
			if (propFeeDetail.getFeeDate().length() > 10) {
				throw new AppBizException(CodeConst.SYS_CODE_1002,
						"收费期间如 2016-09长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getRemark())) {
			if (propFeeDetail.getRemark().length() > 200) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "备注长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getDescription())) {
			if (propFeeDetail.getDescription().length() > 200) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "描述长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getStatus())) {
			if (propFeeDetail.getStatus().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "状态长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getType())) {
			if (propFeeDetail.getType().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002, "1正常2预缴长度超出");
			}
		}

		if (!StringUtils.isBlank(propFeeDetail.getIspre())) {
			if (propFeeDetail.getIspre().length() > 1) {
				throw new AppBizException(CodeConst.SYS_CODE_1002,
						"是否预缴生成的（1否，2是）判断账单是否可撤销长度超出");
			}
		}

		if (oldPropFeeDetail == null) {
			throw new AppBizException(CodeConst.BIS_CODE_68001,
					InfoConst.BIS_INFO_68001);
		}
		if (StringUtils.isBlank(oldPropFeeDetail.getRuleID())
				&& oldPropFeeDetail.getStatus().equals("1")
				&& oldPropFeeDetail.getIspre().equals("1")) {
			throw new AppBizException(CodeConst.BIS_CODE_68001,
					"亲，该缴费明细单已经缴费无法更新");
		}

		oldPropFeeDetail.setTsedit(new Date());
		return this.getSqlSession().update(
				"PropFeeDetailMapper.updateByPrimaryKeySelective",
				propFeeDetail);
	}

	@Override
	public PropFeeDetailDto findPropFeeDetailByID(String propFeeDetailID)
			throws AppBizException {
		if (StringUtils.isBlank(propFeeDetailID)) {

			throw new AppBizException(CodeConst.SYS_CODE_1001, "ID不可为空");
		}

		/************************************************
		 * 判断实体是否存在
		 ************************************************/
		PropFeeDetailDto oldPropFeeDetail = this.getSqlSession()
				.selectOne("PropFeeDetailSearchMapper.selectByPrimaryKey",
						propFeeDetailID);
		if (oldPropFeeDetail == null) {
			throw new AppBizException(CodeConst.BIS_CODE_68001,
					InfoConst.BIS_INFO_68001);
		}

		if (TypeConst.FLAG_OFF.equals(oldPropFeeDetail.getItemStat())) {

			throw new AppBizException(CodeConst.BIS_CODE_68001,
					InfoConst.BIS_INFO_68001);
		}

		return oldPropFeeDetail;
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int deletePropFeeDetailByLogic(String propFeeDetailID)
			throws AppBizException {

		if (StringUtils.isBlank(propFeeDetailID)) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "ID不可为空");
		}
		/************************************************
		 * 判断实体是否存在
		 ************************************************/
		PropFeeDetailDto oldPropFeeDetail = this
				.findPropFeeDetailByID(propFeeDetailID);

		if (StringUtils.isBlank(oldPropFeeDetail.getRuleID())
				&& oldPropFeeDetail.getStatus().equals("1")
				&& oldPropFeeDetail.getIspre().equals("1")) {
			throw new AppBizException(CodeConst.BIS_CODE_68001,
					"亲，该缴费明细单已经缴费无法删除");
		}

		oldPropFeeDetail.setItemStat(TypeConst.FLAG_OFF);
		oldPropFeeDetail.setTsedit(new Date());
		return this.getSqlSession().update(
				"PropFeeDetailMapper.updateByPrimaryKeySelective",
				oldPropFeeDetail);
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int bauthdeleteFeeDetail(Map<String, Object> map)
			throws AppBizException {

		if (map == null || map.size() <= 0) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费细项");
		}
		if (!map.containsKey("feeDetailIDs")) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费细项");
		}

		@SuppressWarnings("unchecked")
		List<String> feeDetailIDs = (List<String>) map.get("feeDetailIDs");
		if (feeDetailIDs == null || feeDetailIDs.size() <= 0) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费细项");
		}
		List<Map<String, Object>> feeDetails = this
				.bauthFindFeeDetail(feeDetailIDs);
		if (feeDetails != null && feeDetails.size() > 0) {
			StringBuffer buffer = new StringBuffer();
			for (Map<String, Object> feeDetail : feeDetails) {
				if (feeDetail.get("unitName") != null) {
					buffer.append(feeDetail.get("buildingName") + "-"
							+ feeDetail.get("unitName") + "-"
							+ feeDetail.get("apartmentNum") + "的 日期为"
							+ feeDetail.get("feeDate") + "缴费类目"
							+ feeDetail.get("feeTypeName") + ",\r\n\t");
				} else {
					buffer.append(feeDetail.get("buildingName") + "-"
							+ feeDetail.get("apartmentNum") + "的 日期为"
							+ feeDetail.get("feeDate") + "缴费类目"
							+ feeDetail.get("feeTypeName") + ",\r\n\t");
				}
			}
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，"
					+ buffer.toString() + "已经缴费无法删除");
		}

		return this.getSqlSession().update(
				"PropFeeDetailBauthMapper.bauthDeleteLg", feeDetailIDs);
	}

	@Override
	public List<Map<String, Object>> bauthFindFeeDetail(
			List<String> feeDetailIDs) throws AppBizException {

		Map<String, Object> paMap = new HashMap<String, Object>();
		paMap.put("feeDetailIDs", feeDetailIDs);
		List<Map<String, Object>> feeDetails = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.bauthFindFeeDetail", paMap);
		return PropertyUtils.turnToEntity(feeDetails);
	}

	@Override
	public List<Map<String, Object>> findFeeDetailByFeeDate(
			Map<String, Object> map) throws AppBizException {
		if (map == null || map.size() <= 0) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费细项");
		}
		if (!map.containsKey("feeDate")) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费日期");
		}
		if (!map.containsKey("commID")) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，小区信息");
		}

		if (map.get("feeDate") == null) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费日期");
		}
		if (map.get("commID") == null) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，小区信息");
		}

		List<Map<String, Object>> feeDetails = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.findFeeDetailByFeeDate", map);
		return PropertyUtils.turnToEntity(feeDetails);
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int deleteFeeDetail(Map<String, Object> map) throws AppBizException {

		if (map == null || map.size() <= 0) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费细项");
		}
		if (!map.containsKey("feeDate")) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费日期");
		}
		if (!map.containsKey("commID")) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，小区信息");
		}

		if (map.get("feeDate") == null) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，缴费日期");
		}
		if (map.get("commID") == null) {
			throw new AppBizException(CodeConst.SYS_CODE_1001, "亲，小区信息");
		}
		/***
		 * 查询可删除的缴费细项
		 */
		List<Map<String, Object>> feeDetails = this.findFeeDetailByFeeDate(map);

		/***
		 * 批量可删除的缴费细项
		 */
		if (feeDetails != null && feeDetails.size() > 0) {
			List<String> feeDetailIDs = new ArrayList<String>();
			for (Map<String, Object> feeDetail : feeDetails) {
				feeDetailIDs.add(feeDetail.get("feeDetailID").toString());
			}
			return this.getSqlSession().update(
					"PropFeeDetailBauthMapper.bauthDeleteLg", feeDetailIDs);
		}
		return 1;
	}

	@Override
	public int deleteFeeDetails(List<String> feeDetails) throws AppBizException {

		return this.getSqlSession().update(
				"PropFeeDetailBauthMapper.bauthDeleteLg", feeDetails);

	}

	@Override
	public Map<String, Map<String, Object>> findFeeDetailMaxDate(
			String apartmentID, List<String> feeTypeIDs, String ispre)
			throws AppBizException {

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("apartmentID", apartmentID);
		map.put("feeTypeIDs", feeTypeIDs);
		map.put("ispre", ispre);

		Map<String, Map<String, Object>> list1 = this.getSqlSession()
				.selectMap("PropFeeDetailMapper.getMaxDate", map, "feeTypeID");
		return list1;
	}

	@Override
	public List<Map<String, Object>> getPropFeeDetails(String apartmentID,
			String feeTypeID, String feeDate) throws AppBizException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("feeTypeID", feeTypeID);
		map.put("feeDate", feeDate);
		map.put("apartmentID", apartmentID);
		List<Map<String, Object>> feeDetails = this.getSqlSession().selectList(
				"PropFeeDetailMapper.getFeeDetails", map);

		return feeDetails;
	}

	@Override
	public List<Map<String, Object>> getFeeDetailsForOffset(String apartmentID,
			String commID) throws AppBizException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("apartmentID", apartmentID);
		map.put("commID", commID);

		List<Map<String, Object>> feeDetails = this.getSqlSession().selectList(
				"PropFeeDetailMapper.getFeeDetailsForOffset", map);

		return feeDetails;
	}

	@Override
	public List<Map<String, Object>> findFeeDetailInfo(Map<String, Object> map)
			throws AppBizException {
		List<Map<String, Object>> feeDetails = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.findFeeDetailInfo", map);
		return feeDetails;
	}

	@Override
	public List<Map<String, Object>> bauthfindPropFeeDetailByMap(
			Map<String, Object> propFeeDetail) throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.batchFindPropFeeDetailByMap",
				propFeeDetail);
		return list;
	}

	@Override
	public List<Map<String, Object>> bauthSearchPropFeeDetails(
			Map<String, Object> propFeeDetail) throws AppBizException {
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.bauthSearchPropFeeDetails",
				propFeeDetail);
		return list;
	}

	@Override
	public List<Map<String, Object>> getFeeDetails(
			Map<String, Object> propFeeDetail) throws AppBizException {
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.getFeeDetails", propFeeDetail);
		return list;
	}

	@Override
	public int changefeeDetailType(ChangeFeeTypeDto changeFeeTypeDto)
			throws AppBizException {
		Map<String, Object> p = new HashMap<>();
		p.put("newFeeTypeID", changeFeeTypeDto.getNewFeeTypeID());
		p.put("oldFeeTypeID", changeFeeTypeDto.getOldFeeTypeID());
		p.put("apartmentIDs", changeFeeTypeDto.getApartmentIDs());
		int n = this.getSqlSession().update(
				"PropFeeDetailMapper.updateFeeDetailType", p);
		// TODO Auto-generated method stub
		return n;
	}

	@Override
	public List<Map<String, Object>> monFeeList(Map<String, Object> param,
			int pageNo, int pageSize) throws AppBizException {
		PageHelper.startPage(pageNo, pageSize);
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.monFeeList", param);
		return list;
	}

	@Override
	public List<Map<String, Object>> monDetail(Map<String, Object> param)
			throws AppBizException {
		// TODO Auto-generated method stub
		return this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.monFeeDteail", param);
	}

	@Override
	public int setFeeDetailsNoPay(String apartmentID,
			List<String> feeDetailIDs, Date paytime) throws AppBizException {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("apartmentID", apartmentID);
		param.put("feeDetailIDs", feeDetailIDs);

		if (paytime == null) {
			paytime = new Date();
		}
		param.put("paytime", paytime);
		// TODO Auto-generated method stub
		return this.getSqlSession().update(
				"PropFeeDetailBauthMapper.updateFeeDetailsNoPay", param);
	}

	@Override
	public List<Map<String, Object>> findMoreFeeDetailInfo(
			Map<String, Object> params) throws AppBizException {
		if (!StringUtils.isBlank(StringUtils.toString(params.get("ispage")))) {

			PageHelper.startPage(
					Integer.parseInt(params.get("pageIndex").toString()),
					Integer.parseInt(params.get("pageSize").toString()));
		}
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.findMoreFeeDetailInfo", params);
		return list;
	}

	@Override
	public List<Map<String, Object>> findropFeeDetailByMap(
			Map<String, Object> propFeeDetail) throws AppBizException

	{

		List<Map<String, Object>> feeDetails = this.getSqlSession().selectList(
				"PropFeeDetailSearchMapper.findropFeeDetailByMap",
				propFeeDetail);

		return feeDetails;
	}
}
